package com.fingard.dsp.bank.directbank.fngrd01.fgnet;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import com.fingard.diagnostics.LogHelper;
import com.fingard.net.ConnState;

public class FgTcpClient {

    private String ip = "";
    private int port = 0;
    private String charset = "";
    Socket socket = null;
    private StringBuilder sbLog = null;

    private int soTimeout = 180000;

    public void setTimeoutMil(int timeoutMil) {
        soTimeout = timeoutMil;
    }

    public FgTcpClient(String p_ip, int p_port, String p_charset, StringBuilder p_sb) {
        ip = p_ip;
        port = p_port;
        charset = p_charset;
        sbLog = p_sb;
    }

    public FgTcpReceiver downloadFileBytes(byte[] p_sendBytes, int p_bytesLen) throws Exception {
        FgTcpReceiver retReceiver = new FgTcpReceiver();
        try {
            socket = new Socket(ip, port);
            socket.setSoTimeout(soTimeout);
        } catch (Exception e) {
            sbLog.append(LogHelper.getStackTrace(e) + "\r\n");
            retReceiver.connState = ConnState.FAIL;
            retReceiver.connMsg = e.getMessage();
            return retReceiver;
        }
        OutputStream tmpOutput = null;
        InputStream tmpInput = null;
        try {
            //sbLog.append("sendBufferSize:" + socket.getSendBufferSize()+",receiveBufferSize: "+socket.getReceiveBufferSize()+"\r\n");
            tmpOutput = socket.getOutputStream();
            tmpOutput.write(p_sendBytes);
            tmpInput = socket.getInputStream();
            //socket.setReceiveBufferSize(204800);65536
            retReceiver.recBytes = new byte[65536];//receiveBufferSize: 65536
            int tmpOffSet = 0;
            retReceiver.contentLength = p_bytesLen + 102;
            sbLog.append("文件大小：" + p_bytesLen + "字节，通讯总字节数：" + retReceiver.contentLength + "\r\n");
            int lastQuotient = 0;
            while (!retReceiver.isCompleted) {
                int tmpReadLen = tmpInput.read(retReceiver.recBytes, tmpOffSet, retReceiver.recBytes.length - tmpOffSet);
                if (tmpReadLen <= 0) {
                    break;
                }
                tmpOffSet += tmpReadLen;
                retReceiver.readedLength = retReceiver.readedLength + tmpReadLen;


                if (retReceiver.readedLength >= 5 && retReceiver.contentStartIndex <= 0) {
                    String tmpRetCode = new String(retReceiver.recBytes, 0, 5, charset);
                    sbLog.append("读取头5字节：" + tmpRetCode + "\r\n");
                    tmpRetCode = tmpRetCode.trim();
                    if (!tmpRetCode.equals("2")) {
                        if (retReceiver.readedLength > 100) {
                            retReceiver.connMsg = new String(retReceiver.recBytes, 0, 100, charset).trim();
                        } else {
                            retReceiver.connMsg = new String(retReceiver.recBytes, 0, retReceiver.readedLength, charset).trim();
                        }
                        break;
                    }
                    retReceiver.contentStartIndex = 102;
                }
                //
                if (retReceiver.recBytes.length < retReceiver.contentLength) {
                    byte[] tmpUnionInfo = new byte[retReceiver.contentLength];//一次性分配内存
                    System.arraycopy(retReceiver.recBytes, 0, tmpUnionInfo, 0, tmpOffSet);
                    retReceiver.recBytes = null;
                    retReceiver.recBytes = tmpUnionInfo;
                }
                int tmpToReadLen = retReceiver.contentLength - tmpOffSet;
                int quotient = tmpOffSet / 100000;
                if (quotient > lastQuotient) {
                    sbLog.append("累计读取字节数：" + retReceiver.readedLength + "，剩余字节数：" + tmpToReadLen + "\r\n");
                    lastQuotient = quotient;
                }
                if (tmpToReadLen <= 0) {
                    retReceiver.isCompleted = true;
                    break;
                }
            }
            tmpOutput.close();
            tmpOutput = null;
            tmpInput.close();
            tmpInput = null;
        } catch (IOException e) {
            sbLog.append(LogHelper.getStackTrace(e));
            retReceiver.connMsg = e.getMessage();
        } finally {
            if (tmpOutput != null) {
                tmpOutput.close();
            }
            if (tmpInput != null) {
                tmpInput.close();
            }
        }
        socket.close();
        return retReceiver;
    }
}
